package com.hm.base.api;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.hm.base.auto.SystemEnvConfigProperties;
import com.hm.base.auto.SystemEnvConfigProperties.BackstageAccreditInfo;
import com.hm.base.auto.helper.HmSessionFactory;
import com.hm.base.auto.su.ControllerResult;
import com.hm.base.auto.su.R.RedisKey;
import com.hm.base.auto.su.R.RedisKey.RedisKeySeEx;
import com.hm.base.auto.su.R.Restful;
import com.hm.common.exception.ErrorCode;
import com.hm.common.exception.ServiceException;
import com.hm.common.redis.jedis.JedisFactory;
import com.hm.common.redis.jedis.su.JedisHandler;
import com.hm.common.redis.jedis.su.JedisHandlerSupport;
import com.hm.common.su.bean.ServerResponse;
import com.hm.common.util.CommonUtil;
import com.hm.common.util.EncryptUtil;
import com.hm.common.util.VerifyCodeUtil;

import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;

/**
 * @author shishun.wang
 * @date 下午3:07:30 2017年6月16日
 * @version 1.0
 * @describe 公共组件api
 */
@Slf4j
@ResponseBody
@RestController
@RequestMapping(Restful.API + "/commmon")
public class CommonApi {

	private static final String SWWAGER_TAG = "公共服务管理";

	@Autowired
	private SystemEnvConfigProperties systemEnvConfigProperties;

	@Autowired
	private JedisHandlerSupport jedisHandler;

	@RequestMapping(value = "/backstage/accredit/info", method = RequestMethod.GET)
	@ApiOperation(tags = SWWAGER_TAG, value = "获取后台系统版本及授权基本信息", httpMethod = "GET", notes = "返回当前后台系统版本及授权基本信息")
	public ResponseEntity<ServerResponse<BackstageAccreditInfo>> loadBackstageAccreditInfo() {
		log.debug("用户{},获取后台系统版本及授权基本信息", HmSessionFactory.currentUserId());
		return ControllerResult.success(systemEnvConfigProperties.getBackstageAccreditInfo());
	}

	@RequestMapping(value = "/lcode", method = RequestMethod.GET)
	@ApiOperation(value = "加载随机验证码", httpMethod = "GET", notes = "加载随机验证码", tags = SWWAGER_TAG)
	public void loadVerifyCode(HttpServletRequest request, HttpServletResponse response,
			@ApiParam(required = true, name = "width", value = "验证码长度") @RequestParam("width") int width,
			@ApiParam(required = true, name = "height", value = "验证码高度") @RequestParam("height") int height,
			@ApiParam(required = true, name = "vcode", value = "验证码") @RequestParam("vcode") String vcode)
			throws Exception {
		log.debug("用户{},加载随机验证码", HmSessionFactory.currentUserId());
		if (CommonUtil.isAnyEmpty(width, height, vcode)) {
			response.getWriter()
					.println(JSON.toJSONString(new ServerResponse<String>().failure("参数错误:width、height、vcode"),
							SerializerFeature.WriteMapNullValue));
			return;
		}

		String code = null;
		try {
			code = EncryptUtil.AES.decrypt(vcode);
		} catch (Exception e) {
			throw ServiceException.warn("无效的验证码");
		}

		{// 设置请求响应头
			response.setHeader("Pragma", "No-cache");
			response.setHeader("Cache-Control", "no-cache");
			response.setDateHeader("Expires", 0);
			response.setContentType("image/jpeg");
		}
		VerifyCodeUtil.outputImage(width, height, response.getOutputStream(), code);
	}

	@RequestMapping(value = "/gcode/{timestamp}/{size}", method = RequestMethod.PATCH)
	@ApiOperation(value = "生成随机验证码", httpMethod = "PATCH", notes = "生成随机验证码", tags = SWWAGER_TAG)
	public ResponseEntity<ServerResponse<String>> generateVerifyCode(
			@ApiParam(required = true, name = "timestamp", value = "生成验证码时间戳,后台验证验证码是否合法也需要传入该时间戳") @PathVariable("timestamp") Long timestamp,
			@ApiParam(required = true, name = "size", value = "生成随机验证码长度") @PathVariable("size") int size)
			throws Exception {
		log.debug("用户{},生成随机验证码", HmSessionFactory.currentUserId());
		String code = EncryptUtil.AES.encrypt(VerifyCodeUtil.generateVerifyCode(size));
		jedisHandler.executeCommand(new JedisHandler() {

			@Override
			public Object handler(JedisFactory jedis) {
				jedis.set(RedisKey.WEB_VERIFICATION_CODE_GROUP + HmSessionFactory.currentUserId() + "_" + timestamp,
						RedisKeySeEx.WEB_VERIFICATION_CODE_GROUP, code);
				return null;
			}
		});

		return ControllerResult.success(code);
	}

	@RequestMapping(value = "/vcode/{timestamp}", method = RequestMethod.POST)
	@ApiOperation(value = "后端验证前台传入验证码是否合法", httpMethod = "POST", notes = "后端验证前台传入验证码是否合法,返回true、false", tags = SWWAGER_TAG)
	public ResponseEntity<ServerResponse<Boolean>> loadVerifyCode2(
			@ApiParam(required = true, name = "timestamp", value = "生成验证码时间戳") @PathVariable("timestamp") Long timestamp,
			@ApiParam(required = true, name = "vcode", value = "验证码") @RequestParam("vcode") String vcode)
			throws Exception {
		log.debug("用户{},后端验证前台传入验证码是否合法", HmSessionFactory.currentUserId());
		if (CommonUtil.isAnyEmpty(timestamp, vcode)) {
			throw ServiceException.warning(ErrorCode.REQUIRED_PARAMETERS_MISSING);
		}

		jedisHandler.executeCommand(new JedisHandler() {

			@Override
			public Object handler(JedisFactory jedis) {
				String key = RedisKey.WEB_VERIFICATION_CODE_GROUP + HmSessionFactory.currentUserId() + "_" + timestamp;
				byte[] result = jedis.get(key.getBytes());
				if (CommonUtil.isEmpty(result)) {
					throw ServiceException.warn("验证码已经失效,请重新获取");
				}

				String redisValue = new String(result);
				
				if (!vcode.trim().toLowerCase().equals(EncryptUtil.AES.decrypt(redisValue).toLowerCase())) {
					throw ServiceException.warn("验证码错误,认证失败");
				}
				return null;
			}
		});

		return ControllerResult.success(true);
	}
}
